#pragma once

#include <iostream>
#include <string>
#include <cerrno>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>

std::string comm_path = "./myfifo";
#define DefaaultFd  -1
#define Creater      1
#define User         2
#define Read         O_RDONLY
#define Write        O_WRONLY
#define BaseSize     4096

class NamedPipe
{
private:
    bool OpenNamedPipe(int mode)
        {
            _fd = open(_fifo_name.c_str(), mode);
            if (_fd < 0)    return false;
            return true;
        }
public:
    NamedPipe(std::string &path, int who)
        : _fifo_name(path), _id(who), _fd(DefaaultFd)
    {
        if (_id == Creater)
        {
            int res = mkfifo(_fifo_name.c_str(), 0666);
            if (res != 0) // 创建管道失败
            {
                perror("mkfifo");
            }
            std::cout << "Creater creat named pipe" << std::endl;
        }
    }
    bool OpenForRead()
    {
        return OpenNamedPipe(Read);
    }
    bool OpenForWrite()
    {
        return OpenNamedPipe(Write);
    }
    // const &: const std::string& xxx  输入型参数
    // *      : std::string* xxx        输出型参数
    // &      : std::string& xxx        输入输出型参数
    int ReadNamedPipe(std::string* out)
    {
        char buffer[BaseSize]{};
        int n = read(_fd, buffer, sizeof buffer);
        if (n > 0)
        {
            buffer[n] = '\0';
            *out = buffer;
        }

        return n;
    }
    int WriteNamedPipe(const std::string& in)
    {
        return write(_fd, in.c_str(), in.size());
    }
    ~NamedPipe()
    {
        if (_id == Creater)
        {
            int res = unlink(_fifo_name.c_str());
            if (res != 0) // 创建管道失败
            {
                perror("unlink");
            }
            std::cout << "Creater free named pipe" << std::endl;
            if (_fd != DefaaultFd)  close(_fd);
        }
    }

private:
    const std::string _fifo_name;
    int _id;
    int _fd;
};
